package controller

import (
	"Demo/ginEssential/common"
	"Demo/ginEssential/dto"
	"Demo/ginEssential/model"
	"Demo/ginEssential/responce"
	"Demo/ginEssential/util"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"golang.org/x/crypto/bcrypt"
)

// Register 实现用户注册相关逻辑
func Register(ctx *gin.Context) {
	DB := common.InitDB()
	//获取参数
	name := ctx.PostForm("name")
	telephone := ctx.PostForm("telephone")
	password := ctx.PostForm("password")
	//数据验证
	//1.手机号码验证
	// code1 := len(telephone)
	// fmt.Println("手机号码长度为：", code1)
	if len(telephone) != 11 {
		responce.Responce(ctx, http.StatusUnprocessableEntity, 422, nil, "手机号必须为11位")
		// ctx.JSON(http.StatusUnprocessableEntity, gin.H{
		// 	"code": 422, "msg": "手机号码必须为11位"})
		return
	}
	// 2.手机密码验证
	if len(password) < 6 {
		responce.Responce(ctx, http.StatusUnprocessableEntity, 422, nil, "密码不能少于6位")
		// ctx.JSON(http.StatusUnprocessableEntity, gin.H{
		// 	"code": 422, "msg": "密码不能少于6位"})
		return
	}
	// 3.如果名称没有传就给10位的随机字符串
	if len(name) == 0 {
		name = util.RandomString(10)
	}
	log.Printf("名称:%s,手机号码:%s,密码: %s\n", name, telephone, password)
	//手机号码是否存在(与数据库的数据比对)
	if isTelephoneExitst(DB, telephone) {
		responce.Responce(ctx, http.StatusUnprocessableEntity, 422, nil, "用户已经存在")
		// ctx.JSON(http.StatusUnprocessableEntity, gin.H{
		// 	"code": 422, "msg": "用户已经存在"})
		return
	}
	// 创建用户
	// 由于密码不可能进行明文保存，因此需要对其进行加密处理
	hasedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		responce.Responce(ctx, http.StatusUnprocessableEntity, 500, nil, "加密错误")
		return
	}
	newUser := model.User{
		Name:      name,
		Telephone: telephone,
		Password:  string(hasedPassword),
	}
	DB.Create(&newUser)
	//返回结果
	responce.Success(ctx, nil, "注册成功")
}

// Login 实现用户登录
func Login(ctx *gin.Context) {
	DB := common.InitDB()
	//获取参数
	name := ctx.PostForm("name")
	telephone := ctx.PostForm("telephone")
	password := ctx.PostForm("password")
	//数据验证
	//1.手机号码验证
	// code1 := len(telephone)
	// fmt.Println("手机号码长度为：", code1)
	if len(telephone) != 11 {
		responce.Responce(ctx, http.StatusUnprocessableEntity, 422, nil, "手机号码必须为11位")
		// ctx.JSON(http.StatusUnprocessableEntity, gin.H{
		// 	"code": 422, "msg": "手机号码必须为11位"})
		return
	}
	// 2.手机密码验证
	if len(password) < 6 {
		responce.Responce(ctx, http.StatusUnprocessableEntity, 422, nil, "密码不能少于6位")
		// ctx.JSON(http.StatusUnprocessableEntity, gin.H{
		// 	"code": 422, "msg": "密码不能少于6位"})
		return
	}

	log.Printf("登录用户名称:%s,手机号码:%s,密码: %s\n", name, telephone, password)
	//手机号码是否存在(与数据库的数据比对)
	var user model.User
	DB.Where("telephone=?", telephone).First(&user)
	if user.ID == 0 {
		// ctx.JSON(http.StatusUnprocessableEntity, gin.H{
		// 	"code": 422, "msg": "用户不存在"})
		responce.Responce(ctx, http.StatusUnprocessableEntity, 422, nil, "用户不存在")
		return
	}
	// 判断用户密码是否正确
	// 用户密码是不可能铭文保存的，因此需要对其进行加密处理
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
		// ctx.JSON(http.StatusUnprocessableEntity, gin.H{
		// 	"code": 400, "msg": "用户密码错误"})
		responce.Responce(ctx, http.StatusUnprocessableEntity, 400, nil, "用户密码错误")
		return
	}

	// 发放 token
	// token := "11"
	token, err := common.ReleaseToken(user)
	if err != nil {
		responce.Responce(ctx, http.StatusUnprocessableEntity, 500, nil, "系统出现异常")
		// ctx.JSON(http.StatusUnprocessableEntity, gin.H{
		// 	"code": 500, "msg": "系统出现异常"})

		log.Printf("token generate error:%v", err)
		return
	}
	//返回结果
	ctx.JSON(200, gin.H{
		"msg":  "登录成功",
		"code": 200,
		"data": gin.H{"token": token},
	})
}

// isTelephoneExitst 与数据库中的数据，验证手机号是否存在
func isTelephoneExitst(db *gorm.DB, telephone string) bool {
	var user model.User
	db.Where("telephone = ?", telephone).First(&user)
	if user.ID != 0 {
		return true
	}
	return false
}

// Info 获取用户信息
func Info(ctx *gin.Context) {
	user, _ := ctx.Get("user")
	ctx.JSON(http.StatusOK, gin.H{"code": 200, "data": gin.H{"user": dto.ToUserDto(user.(model.User))}})

}
